<?php

/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/10/29
 * Time: 14:03
 */
namespace app\api\service;

use app\api\model\User;
use app\lib\enum\ScopeEnum;
use app\lib\exception\BaseException;
use think\Exception;
use think\facade\Cache;

class UserTokenService extends TokenService
{

    protected $appId;
    protected $appSercret;
    protected $code;
    protected $loginUrl;

    public function __construct($code)
    {
        $this->appId = config('app_id');
        $this->appSercret = config('app_secret');
        $this->code = $code;
        $this->loginUrl = sprintf(config('login_url'),$this->appId,$this->appSercret,$this->code);
    }

    public function get(){
        $result = curl_get($this->loginUrl);
        $wxResult = json_decode($result,true);
        if(empty($result)){
            throw new Exception('服务器错误 获取失败');
        }
        if(array_key_exists('errcode',$wxResult)){
            throw new BaseException([
               'code'=> $wxResult['errcode'],
                'msg' => $wxResult['errmsg']
            ]);
        }

        return $this->grantToken($wxResult);


    }

    public function saveToCache($wxResult){
        $key = self::generateToken();
        $value = json_encode($wxResult);
        $expire = config('token_expire_in');

        $result = Cache::set($key,$value,$expire);
        if(!$result){
            throw new BaseException([
                'msg' => '服务器缓存异常',
                'errorCode' => 10005
            ]);
        }
        return $key;
    }

    public function grantToken($wxResult){
        $openid = $wxResult['openid'];
        $user = User::getUserByOpenId($openid);
        if($user){
            $uid = $user->id;
        }else{
            $uid = $this->newUser($wxResult);
        }
        $cacheValue = $this->prepareCachedValue($wxResult,$uid);
        $token = $this->saveToCache($cacheValue);
        return $token;
    }

    private function prepareCachedValue($wxResult, $uid)
    {
        $cachedValue = $wxResult;
        $cachedValue['uid'] = $uid;
        $cachedValue['scope'] = ScopeEnum::User;
        return $cachedValue;
    }

    public function newUser($data){
        $user = User::create([
            'openid'=>$data['openid']
        ]);
        return $user->id;
    }

}